﻿// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

// Upgrade NOTE: upgraded instancing buffer 'Props' to new syntax.

Shader "Aniya/SwingableFadeInstancing" {
	Properties{

		[CurvedWorldBendSettings] _CurvedWorldBendSettings("5|1|1", Vector) = (0, 0, 0, 0)

		_MainTex("Albedo (RGB)", 2D) = "white" {}
		_BumpMap("Normal Map", 2D) = "bump" {}
		_Color("Albedo Color(纹理色）", Color) = (1,1,1,1)//正片叠底

		_Glossiness("Smoothness", Range(0,1)) = 0.5
		_Metallic("Metallic", Range(0,1)) = 0.0
		[HDR]_Emission("Emission(自发光，叠加色)", Color) = (0,0,0,1)
		_EmissionTex("Emission (RGB)", 2D) = "black" {}

		//_InvFade("地面边缘透明", Float) = 1

		_OffsetFactor("Offset Factor", Float) = 0
		_OffsetUnits("Offset Units", Float) = 0

		[HideInInspector] _ShakeIntensity("ShakeIntensity(摇摆幅度)", Range(0,10)) = 1
		[HideInInspector] _ShakePosScale("ShakePosScale(摇摆位置缩放)", Float) = 1
		[HideInInspector] _Softness("Softness(柔软度)", Float) = 1

		[HideInInspector] _SSSStrength("SSS Strength(次表面散射强度)", Float) = 1

		[HideInInspector] _Alpha("透明度", Range(0,1)) = 1
		[HideInInspector] _FixedColor("Fixed Color(固有色)", Color) = (1,1,1,0)//固有色
		[HideInInspector] _Cull("__cull", Float) = 2.0


		// Blending state
		[HideInInspector] _Mode("__mode", Float) = 0.0
		[HideInInspector] _SrcBlend("__src", Float) = 1.0
		[HideInInspector] _DstBlend("__dst", Float) = 0.0
		[HideInInspector] _ZWrite("__zw", Float) = 1.0
	}

	SubShader{
		Tags { "Queue" = "Geometry" "RenderType" = "Opaque" /*"IgnoreProjector"="True"*/ }

		Cull[_Cull]
		Offset[_OffsetFactor],[_OffsetUnits]

		LOD 200

		CGPROGRAM
		// Physically based Standard lighting model, and enable shadows on all light types
		// And generate the shadow pass with instancing support
		#pragma surface surf Standard vertex:vert fullforwardshadows nolightmap nodynlightmap nodirlightmap novertexlights nofog nometa novertexlights //finalcolor:fixedColor //keepalpha  

		// Use shader model 3.0 target, to get nicer looking lighting
		#pragma target 3.5

		// Enable instancing for this shader
		#pragma multi_compile_instancing

		#pragma shader_feature_local __ USE_FADE
		#pragma shader_feature_local __ USE_ALPHA_FADE
		#pragma shader_feature_local __ USE_TEXTURE
		#pragma shader_feature_local __ USER_EMISSION_TEXTURE
		#pragma shader_feature_local __ USE_BUMP_TEXTURE
		#pragma shader_feature_local __ ALWAYS_FACE_CAMERA
		#pragma shader_feature_local __ USE_SWING
		#pragma shader_feature_local __ USE_SSS
		#include "CommonCG.cginc"

		#define CURVEDWORLD_BEND_TYPE_LITTLEPLANET_Y
		#define CURVEDWORLD_BEND_ID_1
		#pragma shader_feature_local CURVEDWORLD_DISABLED_ON
		#pragma shader_feature_local CURVEDWORLD_NORMAL_TRANSFORMATION_ON
		#include "Assets/Amazing Assets/Curved World/Shaders/Core/CurvedWorldTransform.cginc"

		fixed4 _Color;
		fixed4 _FixedColor;
		sampler2D _MainTex;
		float4 _MainTex_ST;
		#if USER_EMISSION_TEXTURE
		sampler2D _EmissionTex;
		#endif
		#if USE_BUMP_TEXTURE
		sampler2D _BumpMap;
		#endif
		#if USE_ALPHA_FADE
		float _Alpha = 1;
		#endif
		#if USE_SSS
		half _SSSStrength = 1;
		#endif
		//sampler2D _CameraDepthTexture;

		fixed3 _Emission;
		half _Glossiness;
		half _Metallic;

		struct Input {
			float4 screenPos;
			float4 color;
			fixed3 emission;
			#if USE_SSS
			float3 viewDir;
			float3 lightDir;
			#endif
			#if USE_BUMP_TEXTURE
			float2 uv_BumpMap;
			#endif
			float4 projPos;
			UNITY_VERTEX_INPUT_INSTANCE_ID
		};

		void vert(inout appdata_full v, out Input o) {
			UNITY_SETUP_INSTANCE_ID(v);
			UNITY_INITIALIZE_OUTPUT(Input, o);
			UNITY_TRANSFER_INSTANCE_ID(v, o);
			UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);

			#if USE_SWING
			ShakeVertex(v.vertex, _ShakeIntensity, _ShakePosScale, _Softness);
			#endif

#if defined(CURVEDWORLD_IS_INSTALLED) && !defined(CURVEDWORLD_DISABLED_ON)
#ifdef CURVEDWORLD_NORMAL_TRANSFORMATION_ON
			CURVEDWORLD_TRANSFORM_VERTEX_AND_NORMAL(v.vertex, v.normal, v.tangent)
#else
			CURVEDWORLD_TRANSFORM_VERTEX(v.vertex)
#endif
#endif

			#if  USE_SSS
			o.lightDir = normalize(_WorldSpaceLightPos0.xyz);
			#endif
			o.color = _Color;
			#if USE_TEXTURE
			fixed4 uv_MainTex = fixed4(TRANSFORM_TEX(v.texcoord, _MainTex), 0, 0);
			o.color = _Color * tex2Dlod(_MainTex, uv_MainTex);
			#endif
			o.emission = _Emission;
			#if USER_EMISSION_TEXTURE
			o.emission *= tex2Dlod(_EmissionTex, v.texcoord);
			#endif
			#if USE_FADE
			o.color.a = ThroughAlpha(v.vertex);
			#endif
			#if USE_BUMP_TEXTURE
			float4 worldPos = mul(unity_ObjectToWorld, v.vertex);
			//！！！！！！！！！这是地面取uv的方式，这里不应该这样处理
			o.uv_BumpMap = float2(worldPos.x, worldPos.z)*0.1;
			#endif
			#if ALWAYS_FACE_CAMERA
			float3 viewDir = ObjSpaceViewDir(v.vertex);
			v.normal *= (1 + step(dot(viewDir, v.normal), 0)*-2);
			#endif

			//o.projPos = ComputeScreenPos(UnityObjectToClipPos(v.vertex));
			//COMPUTE_EYEDEPTH(o.projPos.z);
		}

		UNITY_INSTANCING_BUFFER_START(Props)
		UNITY_INSTANCING_BUFFER_END(Props)

		void surf(Input IN, inout SurfaceOutputStandard o) {
			fixed4 c = IN.color;
			o.Metallic = _Metallic;
			o.Smoothness = _Glossiness;
			o.Emission = IN.emission;
			o.Albedo = c.rgb;
			//o.Albedo = lerp(c.rgb, _FixedColor, _FixedColor.a);
			o.Alpha = c.a;
#if USE_SSS
			/*float3 backLitDir = o.Normal * _SSSStrength + IN.lightDir;
			float backSSS = saturate(dot(IN.viewDir, -backLitDir));
			backSSS = saturate(pow(backSSS, 3));
			o.Albedo *= 1 + backSSS;*/
			fixed sss = 1 - dot(o.Normal, IN.viewDir);
			fixed3 lightDir = IN.lightDir;
			fixed3 worldNormal = WorldNormalVector(IN, o.Normal);
			lightDir.y *= -0.25;
			worldNormal.y *= 0.25;
			sss *= lerp(0.75, 1, dot(-normalize(lightDir), normalize(worldNormal)));
			o.Albedo += sss*sss*sss * _SSSStrength;
#endif
#if USE_ALPHA_FADE
			o.Alpha *= _Alpha;
#endif

			//float sceneZ = LinearEyeDepth(tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(IN.projPos)).r);
			//float partZ = IN.projPos.z;
			//float groundFade = /*1 - */saturate(_InvFade * 0.1 * (sceneZ - partZ));
			////o.Alpha *= groundFade;
			//o.Albedo *= groundFade;
			
#if USE_BUMP_TEXTURE
			o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
#endif

			#if USE_FADE || USE_ALPHA_FADE
				ClipOnAlpha(o.Alpha, IN.screenPos);
			//#else
				//if (groundFade < 1)
					//ClipOnAlpha(o.Alpha, IN.screenPos);
			#endif
		}

		/*void fixedColor(Input IN, SurfaceOutputStandard o, inout fixed4 color)
		{
			color = lerp(color, _FixedColor, _FixedColor.a);
		}*/

		ENDCG

		Pass {
			//顶点有摆动，要让影子跟着正确摆动
			Tags { "LightMode" = "ShadowCaster" }
			AlphaToMask Off

			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma target 2.0
			#pragma multi_compile_shadowcaster
			#pragma multi_compile_instancing // allow instanced shadow pass for most of the shaders
			#pragma shader_feature_local USE_SWING
			#include "UnityCG.cginc"
			#include "CommonCG.cginc"

			#define CURVEDWORLD_BEND_TYPE_LITTLEPLANET_Y
			#define CURVEDWORLD_BEND_ID_1
			#pragma shader_feature_local CURVEDWORLD_DISABLED_ON
			#pragma shader_feature_local CURVEDWORLD_NORMAL_TRANSFORMATION_ON
			#include "Assets/Amazing Assets/Curved World/Shaders/Core/CurvedWorldTransform.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
				float3 normal :NORMAL;
				//float4 tangent : TANGENT;
				UNITY_VERTEX_INPUT_INSTANCE_ID
			};

			struct v2f {
				V2F_SHADOW_CASTER;
				UNITY_VERTEX_OUTPUT_STEREO
			};

			v2f vert(appdata v)
			{

				v2f o;
				UNITY_SETUP_INSTANCE_ID(v);
				UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);

				#if USE_SWING
				ShakeVertex(v.vertex, _ShakeIntensity, _ShakePosScale, _Softness);
				#endif

#if defined(CURVEDWORLD_IS_INSTALLED) && !defined(CURVEDWORLD_DISABLED_ON)
				CURVEDWORLD_TRANSFORM_VERTEX(v.vertex)
#endif

				TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)
				return o;
			}

			float4 frag(v2f i) : SV_Target
			{
				SHADOW_CASTER_FRAGMENT(i)
			}
			ENDCG

		}


//		Pass{
//			Name "ShadowCaster"
//			Tags { "LightMode" = "ShadowCaster" }
//
//			ZWrite On ZTest LEqual
//
//			CGPROGRAM
//			#pragma target 3.0
//
//			// -------------------------------------
//
//
//			#pragma shader_feature_local _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
//			#pragma shader_feature_local _METALLICGLOSSMAP
//			#pragma shader_feature_local _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
//			#pragma shader_feature_local _PARALLAXMAP
//			#pragma multi_compile_shadowcaster
//			#pragma multi_compile_instancing
//			// Uncomment the following line to enable dithering LOD crossfade. Note: there are more in the file to uncomment for other passes.
//			//#pragma multi_compile _ LOD_FADE_CROSSFADE
//			#pragma shader_feature_local USE_SWING
//
//
//#pragma shader_feature_local CURVEDWORLD_BEND_TYPE_CLASSICRUNNER_X_POSITIVE CURVEDWORLD_BEND_TYPE_LITTLEPLANET_Y CURVEDWORLD_BEND_TYPE_CYLINDRICALTOWER_X CURVEDWORLD_BEND_TYPE_SPIRALHORIZONTAL_X_POSITIVE CURVEDWORLD_BEND_TYPE_SPIRALHORIZONTALDOUBLE_X CURVEDWORLD_BEND_TYPE_SPIRALVERTICAL_X_POSITIVE CURVEDWORLD_BEND_TYPE_SPIRALVERTICAL_X_NEGATIVE CURVEDWORLD_BEND_TYPE_TWISTEDSPIRAL_X_POSITIVE CURVEDWORLD_BEND_TYPE_CYLINDRICALROLLOFF_Z
//#define CURVEDWORLD_BEND_ID_1
//#pragma shader_feature_local CURVEDWORLD_DISABLED_ON
//#pragma shader_feature_local CURVEDWORLD_NORMAL_TRANSFORMATION_ON
//
//			#pragma vertex vert
//			#pragma fragment fragShadowCaster
//			#include "UnityStandardShadow.cginc"
//			#include "CommonCG.cginc"
//
//			half _ShakeIntensity;
//			half _ShakePosScale = 1;
//			half _Softness = 1;
//
//			void vert(VertexInput v
//				, out float4 opos : SV_POSITION
//				#ifdef UNITY_STANDARD_USE_SHADOW_OUTPUT_STRUCT
//				, out VertexOutputShadowCaster o
//				#endif
//				#ifdef UNITY_STANDARD_USE_STEREO_SHADOW_OUTPUT_STRUCT
//				, out VertexOutputStereoShadowCaster os
//				#endif
//			)
//			{
//				UNITY_SETUP_INSTANCE_ID(v);
//				#ifdef UNITY_STANDARD_USE_STEREO_SHADOW_OUTPUT_STRUCT
//					UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(os);
//				#endif
//
//				#if USE_SWING
//					ShakeVertex(v.vertex, _ShakeIntensity, _ShakePosScale, _Softness);
//				#endif
//
//				//Curved World
//				#if defined(CURVEDWORLD_IS_INSTALLED) && !defined(CURVEDWORLD_DISABLED_ON)
//					CURVEDWORLD_TRANSFORM_VERTEX(v.vertex);
//				#endif
//
//
//				TRANSFER_SHADOW_CASTER_NOPOS(o,opos)
//				#if defined(UNITY_STANDARD_USE_SHADOW_UVS)
//					o.tex = TRANSFORM_TEX(v.uv0, _MainTex);
//
//					#ifdef _PARALLAXMAP
//						TANGENT_SPACE_ROTATION;
//						o.viewDirForParallax = mul(rotation, ObjSpaceViewDir(v.vertex));
//					#endif
//				#endif
//			}
//
//			ENDCG
//		}



	}

	FallBack "Diffuse"

	CustomEditor "SwingableFadeShaderEditor"
}
